import { _decorator, Component, Node, MeshRenderer, utils, Material, Mesh, math, Vec3, SpotLight, Color, Layers, Vec2 } from 'cc';
import DecoUtil from './DecoUtils';
import earcut from './EarCut';
import { Object3D } from '../Phyic/Object3D';
import { EDITOR_NOT_IN_PREVIEW } from 'cc/env';
import { DecoCtrl } from '../ctrl/DecoCtrl';
import { BuildCtrl } from './BuildCtrl';

// 常量定义
const CONSTANTS = {
    GRAY_COLOR: [0.6, 0.6, 0.65, 0.8],
    WHITE_COLOR: [1.0, 1.0, 1.0, 0.4],
    WALL_HEIGHT: 2200,
    SCALE: 0.001,
    TEXTURE_PHYSICAL_SIZE: 5,
    UV_SCALE: 5,
    TOLERANCE: 0.01
};

// 预生成的索引数组
const INDICES = {
    TOP: [0, 3, 2, 0, 2, 1],
    SIDE: [0, 3, 2, 0, 2, 1, 4, 7, 6, 4, 6, 5, 8, 11, 10, 8, 10, 9, 12, 15, 14, 12, 14, 13],
    DOOR: [0, 3, 2, 0, 2, 1, 4, 7, 6, 4, 6, 5, 8, 11, 10, 8, 10, 9, 12, 15, 14, 12, 14, 13, 16, 19, 18, 16, 18, 17]
};

// 生成颜色数组的工具函数
const generateColors = () => {
    const createColorArray = (color: number[], count: number): number[] => {
        const colors: number[] = [];
        for (let i = 0; i < count; i++) {
            colors.push(...color);
        }
        return colors;
    };

    return {
        TOP: createColorArray(CONSTANTS.GRAY_COLOR, 4),
        SIDE: createColorArray(CONSTANTS.WHITE_COLOR, 16),
        DOOR: [
            ...createColorArray(CONSTANTS.GRAY_COLOR, 4),
            ...createColorArray(CONSTANTS.WHITE_COLOR, 16)
        ]
    };
};

const COLORS = generateColors();

// 类型定义
interface Point { x: number; y: number; id?: number; }
interface Wall { start: number; end: number; ID: string; thick: string; height: string; type: number; convex: number; drawtype: number; }
interface Room { area: string; walls: string[]; pos: Point; name: string; ID: string; label: { name: string, x: number, y: number }[]; }
interface Door { res: string; mirror: number; size: { length: number, thick: number, height: number }; offset: number; pos: Point; highfloor: number; ID: string; type: number; dir: number; rotateZ: number; wallid: string; }
interface Window { res: string; mirror: string; size: { length: number, thick: number, height: number }; pos: Point; highfloor: number; ID: string; type: number; rotateZ: string; wallid: string; }
interface WallConnection { wallId: string; point: Point; connectedWalls: string[]; thickness: number; }
interface ExtendedWallGeometry { startPoint: Point; endPoint: Point; thickness: number; wallId: string; extendedStart?: Point; extendedEnd?: Point; startConnections: string[]; endConnections: string[]; }
interface RoomContent { rooms: Room[]; walls: Wall[]; wallpoints: Point[]; windows: Window[]; doors: Door[]; unit: string; version: string; buildingInfo: { posNum: { x: number, y: number }; scaleNum: { x: number, y: number }; }; }

// RoomStorage 相关接口
export interface RoomData {
    id: string;
    name: string;
    size: number;
    position: { x: number, y: number };
    points: Point[];
    materialType: FloorMaterialType;
}

interface HouseInfo {
    width: number;
    bounds: { minX: number, maxX: number, minY: number, maxY: number };
}

// 材质类型枚举
enum FloorMaterialType {
    DEFAULT = 'default',
    TOILET = 'toilet',
    BEDROOM = 'bedroom'
}

// 工具类：通用辅助方法
class RoomBuilderUtils {
    static arrayContains<T>(array: T[], item: T): boolean {
        return array.indexOf(item) !== -1;
    }

    static stringContains(str: string, search: string): boolean {
        return str.indexOf(search) !== -1;
    }

    static calculateDistance(p1: Point, p2: Point): number {
        return Math.sqrt((p2.x - p1.x) ** 2 + (p2.y - p1.y) ** 2);
    }

    static calculateBounds(points: Point[]): { minX: number, minY: number, maxX: number, maxY: number } {
        const bounds = { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity };
        for (const point of points) {
            bounds.minX = Math.min(bounds.minX, point.x);
            bounds.minY = Math.min(bounds.minY, point.y);
            bounds.maxX = Math.max(bounds.maxX, point.x);
            bounds.maxY = Math.max(bounds.maxY, point.y);
        }
        return bounds;
    }
}

// 数据管理类：合并了 RoomStorage 和 RoomContourAnalyzer 功能
class RoomDataManager {
    private wallMap: Map<string, Wall> = new Map();
    private wallPointMap: Map<number, Point> = new Map();
    private roomMap: Map<string, Room> = new Map();
    // 合并 RoomStorage 的属性
    public rooms: Map<string, RoomData> = new Map();
    public houseInfo: HouseInfo = {
        width: 0,
        bounds: { minX: 0, maxX: 0, minY: 0, maxY: 0 }
    };

    init(roomContent: RoomContent): void {
        this.wallMap.clear();
        this.wallPointMap.clear();
        this.roomMap.clear();
        this.rooms.clear();

        if (roomContent.walls) {
            for (const wall of roomContent.walls) {
                this.wallMap.set(wall.ID, wall);
            }
        }

        if (roomContent.wallpoints) {
            for (const point of roomContent.wallpoints) {
                if (point.id !== undefined) {
                    this.wallPointMap.set(point.id, point);
                }
            }
        }

        if (roomContent.rooms) {
            for (const room of roomContent.rooms) {
                this.roomMap.set(room.ID, room);
            }
        }

        // 分析并存储房间数据
        this.analyzeAndStoreRoomData(roomContent);
    }

    getWall(id: string): Wall | undefined {
        return this.wallMap.get(id);
    }

    getWallPoint(id: number): Point | undefined {
        return this.wallPointMap.get(id);
    }

    getRoom(id: string): Room | undefined {
        return this.roomMap.get(id);
    }

    getAllWalls(): Wall[] {
        return Array.from(this.wallMap.values());
    }

    getAllRooms(): Room[] {
        return Array.from(this.roomMap.values());
    }

    // 根据墙ID获取所属房间
    getRoomsContainingWall(wallId: string): Room[] {
        const rooms: Room[] = [];
        for (const room of this.getAllRooms()) {
            if (room.walls && room.walls.indexOf(wallId) !== -1) {
                rooms.push(room);
            }
        }
        return rooms;
    }

    // 判断墙是否为指定房间独有
    isWallExclusiveToRooms(wallId: string, targetRoomNames: string[]): boolean {
        const containingRooms = this.getRoomsContainingWall(wallId);

        // 如果墙不属于任何房间，返回false
        if (containingRooms.length === 0) return false;

        // 检查是否所有包含此墙的房间都在目标房间列表中
        for (const room of containingRooms) {
            const isTargetRoom = targetRoomNames.some(targetName =>
                room.name && RoomBuilderUtils.stringContains(room.name.toLowerCase(), targetName.toLowerCase())
            );
            if (!isTargetRoom) {
                return false;
            }
        }

        return true;
    }

    addRoom(roomData: RoomData): void {
        this.rooms.set(roomData.id, roomData);
    }

    getRoomData(roomId: string): RoomData | undefined {
        return this.rooms.get(roomId);
    }

    getAllRoomData(): RoomData[] {
        return Array.from(this.rooms.values());
    }

    setHouseInfo(info: Partial<HouseInfo>): void {
        this.houseInfo = { ...this.houseInfo, ...info };
    }

    clearRoomStorage(): void {
        this.rooms.clear();
        this.houseInfo = {
            width: 0,
            bounds: { minX: 0, maxX: 0, minY: 0, maxY: 0 }
        };
    }

    // 获取材质类型 - 公开方法，供其他类使用
    getFloorMaterialType(roomName: string): FloorMaterialType {
        if (!roomName) return FloorMaterialType.TOILET;

        const name = roomName.toLowerCase();
        if (name.includes('厕所') || name.includes('卫生间') || name.includes('洗手间') || name.includes('阳台')) {
            return FloorMaterialType.TOILET;
        }
        if (name.includes('卧室') || name.includes('卧房') || name.includes('睡房')) {
            return FloorMaterialType.BEDROOM;
        }
        return FloorMaterialType.DEFAULT;
    }

    // 分析并存储房间数据
    analyzeAndStoreRoomData(roomContent: RoomContent): void {
        this.clearRoomStorage();

        if (!roomContent?.rooms || !roomContent?.wallpoints) return;

        const allPoints: Point[] = [];

        // 分析每个房间
        for (const room of roomContent.rooms) {
            const roomPoints = this.getRoomContourPoints(room)
            if (roomPoints.length < 3) continue;

            const bounds = this.calculateBounds(roomPoints);
            const maxWidth = (bounds.maxX - bounds.minX + bounds.maxY - bounds.minY) / 2;
            const roomData: RoomData = {
                id: room.ID,
                name: room.name || room.ID,
                size: maxWidth,
                position: room.pos,
                points: roomPoints,
                materialType: this.getFloorMaterialType(room.name)
            };

            this.addRoom(roomData);
            allPoints.push(...roomPoints);
        }

        // 计算整体户型信息
        if (allPoints.length > 0) {
            const houseBounds = this.calculateBounds(allPoints);
            const width = Math.max(houseBounds.maxX - houseBounds.minX, houseBounds.maxY - houseBounds.minY)
            this.setHouseInfo({
                width: width,
                bounds: houseBounds
            });
        }
    }

    private calculateBounds(points: Point[]): { minX: number, maxX: number, minY: number, maxY: number } {
        if (points.length === 0) {
            return { minX: 0, maxX: 0, minY: 0, maxY: 0 };
        }

        let minX = points[0].x;
        let maxX = points[0].x;
        let minY = points[0].y;
        let maxY = points[0].y;

        for (const point of points) {
            minX = Math.min(minX, point.x);
            maxX = Math.max(maxX, point.x);
            minY = Math.min(minY, point.y);
            maxY = Math.max(maxY, point.y);
        }

        return { minX, maxX, minY, maxY };
    }

    getRoomContourPoints(room: Room): Point[] {
        const wallGraph = this.buildWallGraph(room.walls);
        const orderedPoints = this.traceRoomContour(wallGraph);
        return orderedPoints.length >= 3 ? orderedPoints : [];
    }

    private buildWallGraph(roomWallIds: string[]): Map<number, any[]> {
        const graph = new Map<number, any[]>();

        for (const wallId of roomWallIds) {
            const wall = this.getWall(wallId);
            if (!wall) continue;

            const startId = Number(wall.start);
            const endId = Number(wall.end);

            if (!graph.has(startId)) graph.set(startId, []);
            if (!graph.has(endId)) graph.set(endId, []);

            graph.get(startId).push({ pointId: endId, wallId });
            graph.get(endId).push({ pointId: startId, wallId });
        }

        return graph;
    }

    private traceRoomContour(graph: Map<number, any[]>): Point[] {
        if (graph.size === 0) return [];

        let startPointId: number | null = null;
        let minConnections = Infinity;

        const graphKeys = Array.from(graph.keys());
        for (const pointId of graphKeys) {
            const connections = graph.get(pointId);
            if (connections && connections.length < minConnections) {
                minConnections = connections.length;
                startPointId = pointId;
            }
        }

        if (!startPointId) return [];

        const visitedWalls = new Set<string>();
        const contourPoints: Point[] = [];
        let currentPointId = startPointId;
        let previousWallId: string | null = null;
        let iterations = 0;

        do {
            const currentPoint = this.getWallPoint(currentPointId);
            if (!currentPoint) break;

            contourPoints.push(currentPoint);

            const connections = graph.get(currentPointId) || [];
            let nextConnection = null;

            for (const conn of connections) {
                if (!visitedWalls.has(conn.wallId) && conn.wallId !== previousWallId) {
                    nextConnection = conn;
                    break;
                }
            }

            if (!nextConnection) break;

            visitedWalls.add(nextConnection.wallId);
            previousWallId = nextConnection.wallId;
            currentPointId = nextConnection.pointId;
            iterations++;

        } while (currentPointId !== startPointId && iterations < 100);

        if (contourPoints.length > 3 && contourPoints[0].id === contourPoints[contourPoints.length - 1].id) {
            contourPoints.pop();
        }

        return contourPoints;
    }
}

// 地板几何数据接口
interface FloorGeometryData {
    positions: number[];
    indices: number[];
    normals: number[];
    uvs: number[];
    roomId: string;
    roomName: string;
}

// 优化后的地板生成类：支持按材质类型合并mesh
class FloorGenerator {
    constructor(private dataManager: RoomDataManager) { }

    createFloorsForRooms(roomContent: RoomContent): void {
        if (!roomContent?.rooms) return;

        // 按材质类型分组收集地板几何数据
        const floorDataByMaterial = new Map<FloorMaterialType, FloorGeometryData[]>();

        for (const room of roomContent.rooms) {
            const polyPoints = this.dataManager.getRoomData(room.ID).points;
            if (polyPoints.length < 3) continue;

            const floorGeometry = this.createFloorGeometryForRoom(polyPoints, room);
            if (!floorGeometry) continue;

            // 使用 dataManager 的方法获取材质类型
            const materialType = this.dataManager.getFloorMaterialType(room.name);

            if (!floorDataByMaterial.has(materialType)) {
                floorDataByMaterial.set(materialType, []);
            }
            floorDataByMaterial.get(materialType).push(floorGeometry);
        }

        // 为每种材质类型创建合并的mesh
        this.createCombinedFloorMeshes(floorDataByMaterial);
    }

    private createFloorGeometryForRoom(points: Point[], room: Room): FloorGeometryData | null {
        if (!points || points.length < 3) return null;

        let normPoints = points;
        if (normPoints.length > 3 &&
            normPoints[0].x === normPoints[normPoints.length - 1].x &&
            normPoints[0].y === normPoints[normPoints.length - 1].y) {
            normPoints = normPoints.slice(0, -1);
        }

        const positions: number[] = [];
        for (const p of normPoints) {
            positions.push(p.x, p.y);
        }

        const indices = earcut(positions);
        if (indices.length === 0 || indices.length % 3 !== 0) return null;

        const floorPositions: number[] = [];
        const normals: number[] = [];
        const uvs: number[] = [];

        const bounds = RoomBuilderUtils.calculateBounds(normPoints);

        for (const p of normPoints) {
            floorPositions.push(p.x, 0, p.y);
            normals.push(0, 1, 0);
            uvs.push(
                (p.x - bounds.minX) / CONSTANTS.TEXTURE_PHYSICAL_SIZE,
                (p.y - bounds.minY) / CONSTANTS.TEXTURE_PHYSICAL_SIZE
            );
        }

        return {
            positions: floorPositions,
            indices: indices,
            normals: normals,
            uvs: uvs,
            roomId: room.ID,
            roomName: room.name || room.ID
        };
    }

    private getMaterialByType(materialType: FloorMaterialType): Material | null {
        switch (materialType) {
            case FloorMaterialType.TOILET:
                return BuildCtrl.ins.toiletMat || BuildCtrl.ins.floorMaterial;
            case FloorMaterialType.BEDROOM:
                return BuildCtrl.ins.roomMaterial || BuildCtrl.ins.floorMaterial;
            case FloorMaterialType.DEFAULT:
            default:
                return BuildCtrl.ins.floorMaterial;
        }
    }

    private createCombinedFloorMeshes(floorDataByMaterial: Map<FloorMaterialType, FloorGeometryData[]>): void {
        // 使用传统循环替代 entries()
        const materialTypes = Array.from(floorDataByMaterial.keys());

        for (const materialType of materialTypes) {
            const geometryDataArray = floorDataByMaterial.get(materialType);
            if (!geometryDataArray || geometryDataArray.length === 0) continue;

            const combinedMesh = this.createCombinedFloorMesh(geometryDataArray, materialType);
            if (combinedMesh) {
                const material = this.getMaterialByType(materialType);
                if (material) {
                    const meshRenderer = combinedMesh.getComponent(MeshRenderer);
                    if (meshRenderer) {
                        meshRenderer.material = material;
                    }
                }
            }
        }
    }

    private createCombinedFloorMesh(geometryDataArray: FloorGeometryData[], materialType: FloorMaterialType): Node | null {
        if (geometryDataArray.length === 0) return null;

        // 计算总顶点数和索引数
        let totalVertices = 0;
        let totalIndices = 0;

        for (const data of geometryDataArray) {
            totalVertices += data.positions.length / 3;
            totalIndices += data.indices.length;
        }

        // 创建合并后的数据数组
        const mergedData = {
            positions: new Float32Array(totalVertices * 3),
            normals: new Float32Array(totalVertices * 3),
            uvs: new Float32Array(totalVertices * 2),
            indices: new Uint32Array(totalIndices)
        };

        let vertexOffset = 0;
        let positionOffset = 0;
        let normalOffset = 0;
        let uvOffset = 0;
        let indexOffset = 0;

        // 合并所有地板几何数据
        for (const data of geometryDataArray) {
            const vertexCount = data.positions.length / 3;
            // 复制顶点数据
            mergedData.positions.set(data.positions, positionOffset);
            mergedData.normals.set(data.normals, normalOffset);
            mergedData.uvs.set(data.uvs, uvOffset);

            // 复制索引数据（需要加上顶点偏移）
            for (let i = 0; i < data.indices.length; i++) {
                mergedData.indices[indexOffset + i] = data.indices[i] + vertexOffset;
            }

            // 更新偏移量
            vertexOffset += vertexCount;
            positionOffset += data.positions.length;
            normalOffset += data.normals.length;
            uvOffset += data.uvs.length;
            indexOffset += data.indices.length;
        }

        // 计算边界框和切线
        const boundingBox = DecoUtil.calculateBoundingBox(Array.from(mergedData.positions));
        const tangent = DecoUtil.calculateTangents(
            Array.from(mergedData.positions),
            Array.from(mergedData.normals),
            Array.from(mergedData.uvs),
            Array.from(mergedData.indices)
        );
        // 创建mesh
        const meshOptions: any = {
            positions: Array.from(mergedData.positions),
            normals: Array.from(mergedData.normals),
            uvs: Array.from(mergedData.uvs),
            indices: Array.from(mergedData.indices),
            tangents: tangent,
            minPos: boundingBox.minPos,
            maxPos: boundingBox.maxPos
        };

        const mesh = utils.MeshUtils.createMesh(meshOptions);
        mesh.name = `CombinedFloor_${materialType}`;

        // 创建节点
        const floorNode = new Node(`CombinedFloor_${materialType}`);
        floorNode.parent = BuildCtrl.ins.room;
        const meshRenderer = floorNode.addComponent(MeshRenderer);
        meshRenderer.mesh = mesh;

        console.log(`创建合并地板网格: ${materialType}, 包含 ${geometryDataArray.length} 个房间, ${totalVertices} 个顶点, ${totalIndices / 3} 个三角形`);

        return floorNode;
    }
}

// 灯光生成类：处理房间照明
class LightGenerator {
    private roomTypesWithLight = ['餐厅', '客厅', '客餐厅', '卧室', '阳台', '厨房'];

    constructor(
        private dataManager: RoomDataManager,
        private wallHeight: number,
        private scale: number
    ) { }

    createRoomLights(): void {
        const rooms = this.dataManager.getAllRooms();
        if (!rooms.length) return;

        for (const room of rooms) {
            if (!this.shouldCreateLight(room.name)) continue;

            const roomData = this.dataManager.getRoomData(room.ID);
            if (!roomData) continue;

            if (roomData.size >= 2) {
                const { center, size } = this.calculateLightPosition(roomData);
                this.createSpotLightForRoom(room, center, size);
            }


        }
    }

    private shouldCreateLight(roomName: string): boolean {
        return this.roomTypesWithLight.some(type =>
            roomName && RoomBuilderUtils.stringContains(roomName, type)
        );
    }

    private calculateLightPosition(roomData: RoomData): { center: Vec3, size: { width: number } } {
        // 优先使用 roomData 中已计算好的尺寸信息
        const width = roomData.size;

        // 如果 roomData 没有足够信息，回退到轮廓计算
        let finalWidth = width;
        let centerX = roomData.position.x;
        let centerY = roomData.position.y;

        return {
            center: new Vec3(
                centerX,
                this.wallHeight * this.scale * 1.3,
                centerY
            ),
            size: {
                width: finalWidth,
            }
        };
    }

    private createSpotLightForRoom(room: Room, center: Vec3, size: { width: number }): void {
        const lightNode = new Node(`SpotLight_${room.name || room.ID}`);
        lightNode.parent = BuildCtrl.ins.room;
        lightNode.setPosition(center);
        lightNode.setRotationFromEuler(-90, 0, 0);

        const spotLight = lightNode.addComponent(SpotLight);
        if (spotLight) {
            const avgSize = size.width;
            spotLight.spotAngle = math.clamp(120 + (avgSize * 20), 120, 180);
            spotLight.range = avgSize * 1.5;
            spotLight.size = avgSize * 0.6;
            spotLight.angleAttenuationStrength = 0.2

            spotLight.luminance = this.calculateLuminanceForRoom(room.name, avgSize);
            spotLight.color = this.getLightColorForRoom(room.name);
            spotLight.shadowEnabled = false;
            spotLight.visibility = Layers.Enum.UI_3D + Layers.Enum.DEFAULT;
        }
    }

    private calculateLuminanceForRoom(roomName: string, avgSize: number): number {
        // 可以利用 dataManager 中的材质类型来简化判断
        const materialType = this.dataManager.getFloorMaterialType(roomName);
        let baseLuminance = 1;

        switch (materialType) {
            case FloorMaterialType.BEDROOM:
                baseLuminance = 5;
                break;
            case FloorMaterialType.TOILET:
                baseLuminance = 4;
                break;
            default:
                baseLuminance = 6; // 客厅等其他房间

                break;
        }

        const sizeFactor = Math.sqrt(avgSize) / 6;
        return math.clamp(baseLuminance * sizeFactor, 6, 18);
    }

    private getLightColorForRoom(roomName: string): Color {
        const color = new Color();
        const materialType = this.dataManager.getFloorMaterialType(roomName);

        switch (materialType) {
            case FloorMaterialType.BEDROOM:
                color.set(255, 240, 200); // 温暖的黄光
                break;
            case FloorMaterialType.TOILET:
                color.set(255, 255, 240); // 偏白的光
                break;
            default:
                color.set(255, 245, 230); // 客厅等通用光
                break;
        }

        return color;
    }
}

// 家具定位类：处理家具最佳位置计算
class FurniturePositioner {
    private type = ["sofa", 'bed', 'table', 'chair'];
    private scales = [0.9, 0.9, 0.7, 0.3];
    private rotate = [-90, 90, 90, -90];

    constructor(private dataManager: RoomDataManager) { }

    getWallsForFurniturePosition(roomContent: RoomContent): any {
        const wallsWithDoorsAndWindows = new Set<string>();

        if (roomContent.doors) {
            for (const door of roomContent.doors) {
                if (door.wallid) wallsWithDoorsAndWindows.add(door.wallid);
            }
        }
        if (roomContent.windows) {
            for (const window of roomContent.windows) {
                if (window.wallid) wallsWithDoorsAndWindows.add(window.wallid);
            }
        }

        const roomWallAnalysis: any = {};

        if (roomContent.rooms) {
            for (const room of roomContent.rooms) {
                if (room.name === "阳台" || room.name === "卫生间" || room.name === "餐厅") continue;

                const roomWallsWithoutDoorsAndWindows = room.walls.filter(wallId =>
                    !wallsWithDoorsAndWindows.has(wallId)
                );

                const wallLengths = roomWallsWithoutDoorsAndWindows.map(wallId => {
                    const wall = this.dataManager.getWall(wallId);
                    if (!wall) return { length: 0 };

                    const startPoint = this.dataManager.getWallPoint(wall.start);
                    const endPoint = this.dataManager.getWallPoint(wall.end);
                    if (!startPoint || !endPoint) return { length: 0 };

                    const distance = Math.abs(endPoint.x - startPoint.x) + Math.abs(endPoint.y - startPoint.y);
                    return { length: distance, start: startPoint, end: endPoint, pos: room.pos };
                });

                wallLengths.sort((a, b) => b.length - a.length);
                roomWallAnalysis[room.name] = wallLengths.slice(0, 2);
            }
        }

        return roomWallAnalysis;
    }

    generateFurnitureBestPositions(roomWallAnalysis: any): any {
        const furniturePositions: any = {};

        for (const roomName in roomWallAnalysis) {
            const walls = roomWallAnalysis[roomName];
            if (walls.length === 0) continue;

            const roomNameLower = roomName.toLowerCase();

            if (RoomBuilderUtils.stringContains(roomNameLower, "卧室")) {
                if (walls[0] && walls[0].length >= 1.8) {
                    furniturePositions.bed = { ...walls[0], roomName };
                }
                if (walls[1]) {
                    furniturePositions.chair = { ...walls[1], roomName };
                } else if (walls[0] && !furniturePositions.bed) {
                    furniturePositions.chair = { ...walls[0], roomName };
                }
            } else if (RoomBuilderUtils.stringContains(roomNameLower, "客厅")) {
                if (walls[0] && walls[0].length >= 1.5) {
                    furniturePositions.sofa = { ...walls[0], roomName };
                }
                if (walls[1]) {
                    furniturePositions.table = { ...walls[1], roomName };
                }
            } else if (RoomBuilderUtils.stringContains(roomNameLower, "客餐厅") || RoomBuilderUtils.stringContains(roomNameLower, "餐厅")) {
                if (walls[0] && !furniturePositions.table) {
                    furniturePositions.table = { ...walls[0], roomName };
                }
                if (RoomBuilderUtils.stringContains(roomNameLower, "客餐厅") && walls[1] && !furniturePositions.sofa) {
                    furniturePositions.sofa = { ...walls[1], roomName };
                }
            }
        }

        return furniturePositions;
    }
}

// 墙体几何数据接口
interface WallGeometryData {
    colors: number[];
    positions: number[];
    indices: number[];
    normals: number[];
    uvs: number[];
}

// 墙体段落接口
interface WallSegment {
    start: Point;
    end: Point;
    thick: number;
}

// 门窗段落接口
interface DoorSegment {
    start: number;
    end: number;
    door: Door;
}

// 墙体扩展几何计算类
class WallExtensionCalculator {
    private wallConnections: Map<string, WallConnection> = new Map();
    private extendedWallGeometries: ExtendedWallGeometry[] = [];

    constructor(private dataManager: RoomDataManager, private scale: number) { }

    calculateWallExtensions(): ExtendedWallGeometry[] {
        this.analyzeWallConnections();
        this.calculateExtensions();
        return this.extendedWallGeometries;
    }

    private analyzeWallConnections(): void {
        this.wallConnections.clear();
        const pointToWalls = new Map<number, string[]>();

        for (const wall of this.dataManager.getAllWalls()) {
            const startId = wall.start;
            const endId = wall.end;

            if (!pointToWalls.has(startId)) pointToWalls.set(startId, []);
            if (!pointToWalls.has(endId)) pointToWalls.set(endId, []);

            pointToWalls.get(startId).push(wall.ID);
            pointToWalls.get(endId).push(wall.ID);
        }

        const pointIds = Array.from(pointToWalls.keys());
        for (const pointId of pointIds) {
            const wallIds = pointToWalls.get(pointId);
            const point = this.dataManager.getWallPoint(pointId);
            if (!point || !wallIds || wallIds.length < 2) continue;

            for (const wallId of wallIds) {
                const wall = this.dataManager.getWall(wallId);
                if (!wall) continue;

                const connectionKey = `${wallId}_${pointId}`;
                this.wallConnections.set(connectionKey, {
                    wallId: wallId,
                    point: point,
                    connectedWalls: wallIds.filter(id => id !== wallId),
                    thickness: parseFloat(wall.thick) * this.scale
                });
            }
        }
    }

    private calculateExtensions(): void {
        this.extendedWallGeometries = [];
        const wallGeometries = new Map<string, ExtendedWallGeometry>();

        for (const wall of this.dataManager.getAllWalls()) {
            const startPoint = this.dataManager.getWallPoint(wall.start);
            const endPoint = this.dataManager.getWallPoint(wall.end);
            if (!startPoint || !endPoint) continue;

            const thickness = parseFloat(wall.thick) * this.scale;
            const startConnKey = `${wall.ID}_${startPoint.id}`;
            const endConnKey = `${wall.ID}_${endPoint.id}`;
            const startConnection = this.wallConnections.get(startConnKey);
            const endConnection = this.wallConnections.get(endConnKey);

            const geometry: ExtendedWallGeometry = {
                startPoint,
                endPoint,
                thickness,
                wallId: wall.ID,
                startConnections: startConnection ? startConnection.connectedWalls : [],
                endConnections: endConnection ? endConnection.connectedWalls : []
            };

            wallGeometries.set(wall.ID, geometry);
        }

        const wallIds = Array.from(wallGeometries.keys());
        for (const wallId of wallIds) {
            const geometry = wallGeometries.get(wallId);
            if (geometry) {
                this.calculateExtendedPoints(geometry);
                this.extendedWallGeometries.push(geometry);
            }
        }
    }

    private calculateExtendedPoints(geometry: ExtendedWallGeometry): void {
        const { startPoint, endPoint, startConnections, endConnections, wallId } = geometry;
        const dirX = endPoint.x - startPoint.x;
        const dirZ = endPoint.y - startPoint.y;
        const length = Math.sqrt(dirX * dirX + dirZ * dirZ);
        const dirNormX = dirX / length;
        const dirNormZ = dirZ / length;

        geometry.extendedStart = { ...startPoint };
        geometry.extendedEnd = { ...endPoint };

        if (startConnections.length > 0) {
            const adjustment = this.calculatePointAdjustment(wallId, startPoint, startConnections);
            if (adjustment !== 0) {
                geometry.extendedStart = {
                    x: startPoint.x - dirNormX * adjustment,
                    y: startPoint.y - dirNormZ * adjustment
                };
            }
        }

        if (endConnections.length > 0) {
            const adjustment = this.calculatePointAdjustment(wallId, endPoint, endConnections);
            if (adjustment !== 0) {
                geometry.extendedEnd = {
                    x: endPoint.x + dirNormX * adjustment,
                    y: endPoint.y + dirNormZ * adjustment
                };
            }
        }
    }

    private calculatePointAdjustment(wallId: string, point: Point, connectedWalls: string[]): number {
        const currentWall = this.dataManager.getWall(wallId);
        if (!currentWall) return 0;

        const connectionTypes = this.analyzeConnectionTypes(wallId, point, connectedWalls);

        if (connectionTypes.tTypeConnections.length > 0) {
            const maxThickness = Math.max(...connectionTypes.tTypeConnections.map(conn => conn.thickness));
            return -maxThickness / 2;
        }

        if (connectionTypes.lTypeConnections.length > 0) {
            const allWallIds = [wallId, ...connectionTypes.lTypeConnections.map(conn => conn.wallId)].sort();

            if (allWallIds[0] === wallId) {
                const maxThickness = Math.max(
                    parseFloat(currentWall.thick) * this.scale,
                    ...connectionTypes.lTypeConnections.map(conn => conn.thickness)
                );
                return maxThickness / 2;
            } else {
                const extendingWallId = allWallIds[0];
                const extendingWall = connectionTypes.lTypeConnections.find(conn => conn.wallId === extendingWallId);
                if (extendingWall) {
                    return -extendingWall.thickness / 2;
                }
            }
        }

        return 0;
    }

    private analyzeConnectionTypes(wallId: string, point: Point, connectedWalls: string[]): {
        tTypeConnections: { wallId: string, thickness: number }[],
        lTypeConnections: { wallId: string, thickness: number }[]
    } {
        const currentWall = this.dataManager.getWall(wallId);
        if (!currentWall) return { tTypeConnections: [], lTypeConnections: [] };

        const tTypeConnections: { wallId: string, thickness: number }[] = [];
        const lTypeConnections: { wallId: string, thickness: number }[] = [];

        for (const connectedWallId of connectedWalls) {
            const connectedWall = this.dataManager.getWall(connectedWallId);
            if (!connectedWall) continue;

            const thickness = parseFloat(connectedWall.thick) * this.scale;
            const angle = this.calculateAngleBetweenWalls(currentWall, connectedWall, point);

            if (Math.abs(angle - Math.PI / 2) < 0.1) {
                if (this.isPointOnWallMiddle(currentWall, point)) {
                    tTypeConnections.push({ wallId: connectedWallId, thickness });
                } else {
                    lTypeConnections.push({ wallId: connectedWallId, thickness });
                }
            } else {
                lTypeConnections.push({ wallId: connectedWallId, thickness });
            }
        }

        return { tTypeConnections, lTypeConnections };
    }

    private calculateAngleBetweenWalls(wall1: Wall, wall2: Wall, connectionPoint: Point): number {
        const wall1Start = this.dataManager.getWallPoint(wall1.start);
        const wall1End = this.dataManager.getWallPoint(wall1.end);
        const wall2Start = this.dataManager.getWallPoint(wall2.start);
        const wall2End = this.dataManager.getWallPoint(wall2.end);

        if (!wall1Start || !wall1End || !wall2Start || !wall2End) return 0;

        let dir1: { x: number, y: number };
        if (wall1Start.id === connectionPoint.id) {
            dir1 = { x: wall1End.x - wall1Start.x, y: wall1End.y - wall1Start.y };
        } else {
            dir1 = { x: wall1Start.x - wall1End.x, y: wall1Start.y - wall1End.y };
        }

        let dir2: { x: number, y: number };
        if (wall2Start.id === connectionPoint.id) {
            dir2 = { x: wall2End.x - wall2Start.x, y: wall2End.y - wall2Start.y };
        } else {
            dir2 = { x: wall2Start.x - wall2End.x, y: wall2Start.y - wall2End.y };
        }

        const dot = dir1.x * dir2.x + dir1.y * dir2.y;
        const mag1 = Math.sqrt(dir1.x * dir1.x + dir1.y * dir1.y);
        const mag2 = Math.sqrt(dir2.x * dir2.x + dir2.y * dir2.y);

        if (mag1 === 0 || mag2 === 0) return 0;
        return Math.acos(Math.max(-1, Math.min(1, dot / (mag1 * mag2))));
    }

    private isPointOnWallMiddle(wall: Wall, point: Point): boolean {
        if (wall.start === point.id || wall.end === point.id) {
            return false;
        }

        const startPoint = this.dataManager.getWallPoint(wall.start);
        const endPoint = this.dataManager.getWallPoint(wall.end);
        if (!startPoint || !endPoint) return false;

        const distToLine = this.pointToLineDistance(point, startPoint, endPoint);
        if (distToLine > CONSTANTS.TOLERANCE) return false;

        const minX = Math.min(startPoint.x, endPoint.x) - CONSTANTS.TOLERANCE;
        const maxX = Math.max(startPoint.x, endPoint.x) + CONSTANTS.TOLERANCE;
        const minY = Math.min(startPoint.y, endPoint.y) - CONSTANTS.TOLERANCE;
        const maxY = Math.max(startPoint.y, endPoint.y) + CONSTANTS.TOLERANCE;

        return point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY;
    }

    private pointToLineDistance(point: Point, lineStart: Point, lineEnd: Point): number {
        const A = point.x - lineStart.x;
        const B = point.y - lineStart.y;
        const C = lineEnd.x - lineStart.x;
        const D = lineEnd.y - lineStart.y;

        const dot = A * C + B * D;
        const lenSq = C * C + D * D;

        if (lenSq === 0) return Math.sqrt(A * A + B * B);

        let param = dot / lenSq;
        param = Math.max(0, Math.min(1, param));

        const xx = lineStart.x + param * C;
        const yy = lineStart.y + param * D;

        const dx = point.x - xx;
        const dy = point.y - yy;

        return Math.sqrt(dx * dx + dy * dy);
    }
}

// 墙体几何生成类
class WallGeometryGenerator {
    constructor(private scale: number) { }

    generateWallGeometry(
        startPoint: { x: number, y: number },
        endPoint: { x: number, y: number },
        thickness: number,
        height: number,
        type: 'top' | 'side' | 'full'
    ): { positions: number[], normals: number[], uvs: number[] } {
        const dirX = endPoint.x - startPoint.x;
        const dirZ = endPoint.y - startPoint.y;
        const dirLength = Math.sqrt(dirX * dirX + dirZ * dirZ);

        if (dirLength < 0.001) {
            return { positions: [], normals: [], uvs: [] };
        }

        const dirNormalizedX = dirX / dirLength;
        const dirNormalizedZ = dirZ / dirLength;
        const normalX = -dirNormalizedZ;
        const normalZ = dirNormalizedX;
        const thickHalfX = normalX * thickness / 2;
        const thickHalfZ = normalZ * thickness / 2;

        const vertices = [
            [startPoint.x - thickHalfX, 0, startPoint.y - thickHalfZ],
            [endPoint.x - thickHalfX, 0, endPoint.y - thickHalfZ],
            [endPoint.x + thickHalfX, 0, endPoint.y + thickHalfZ],
            [startPoint.x + thickHalfX, 0, startPoint.y + thickHalfZ],
            [startPoint.x - thickHalfX, height, startPoint.y - thickHalfZ],
            [endPoint.x - thickHalfX, height, endPoint.y - thickHalfZ],
            [endPoint.x + thickHalfX, height, endPoint.y + thickHalfZ],
            [startPoint.x + thickHalfX, height, startPoint.y + thickHalfZ]
        ];

        let positions: number[] = [];
        let normals: number[] = [];
        let uvs: number[] = [];

        if (type === 'top') {
            positions = [
                ...vertices[4], ...vertices[5], ...vertices[6], ...vertices[7]
            ];
            for (let i = 0; i < 4; i++) {
                normals.push(0, 1, 0);
            }
            uvs = [0, 0, dirLength / CONSTANTS.UV_SCALE, 0, dirLength / CONSTANTS.UV_SCALE, thickness / CONSTANTS.UV_SCALE, 0, thickness / CONSTANTS.UV_SCALE];
        } else {
            const sideConfig = [
                { indices: [0, 1, 5, 4], normal: [-normalX, 0, -normalZ] },
                { indices: [1, 2, 6, 5], normal: [dirNormalizedX, 0, dirNormalizedZ] },
                { indices: [2, 3, 7, 6], normal: [normalX, 0, normalZ] },
                { indices: [3, 0, 4, 7], normal: [-dirNormalizedX, 0, -dirNormalizedZ] }
            ];

            if (type === 'side') {
                for (const side of sideConfig) {
                    positions.push(
                        ...vertices[side.indices[0]],
                        ...vertices[side.indices[1]],
                        ...vertices[side.indices[2]],
                        ...vertices[side.indices[3]]
                    );
                    for (let i = 0; i < 4; i++) {
                        normals.push(...side.normal);
                    }
                }
                uvs = this.calculateWallSideUVs(height, dirLength, thickness);
            } else {
                positions = [
                    ...vertices[4], ...vertices[5], ...vertices[6], ...vertices[7]
                ];
                for (let i = 0; i < 4; i++) {
                    normals.push(0, 1, 0);
                }

                for (const side of sideConfig) {
                    positions.push(
                        ...vertices[side.indices[0]],
                        ...vertices[side.indices[1]],
                        ...vertices[side.indices[2]],
                        ...vertices[side.indices[3]]
                    );
                    for (let i = 0; i < 4; i++) {
                        normals.push(...side.normal);
                    }
                }
                uvs = this.calculateDoorUVs(height, dirLength, thickness);
            }
        }

        return { positions, normals, uvs };
    }

    private calculateWallSideUVs(height: number, length: number, thickness: number): number[] {
        const h = height / CONSTANTS.UV_SCALE;
        const l = length / CONSTANTS.UV_SCALE;
        const t = thickness / CONSTANTS.UV_SCALE;

        return [
            0, 0, l, 0, l, h, 0, h,
            0, 0, t, 0, t, h, 0, h,
            0, 0, l, 0, l, h, 0, h,
            0, 0, t, 0, t, h, 0, h
        ];
    }

    private calculateDoorUVs(height: number, length: number, thickness: number): number[] {
        const h = height / CONSTANTS.UV_SCALE;
        const l = length / CONSTANTS.UV_SCALE;
        const t = thickness / CONSTANTS.UV_SCALE;

        return [
            0, 0, l, 0, l, t, 0, t,
            ...this.calculateWallSideUVs(height, length, thickness)
        ];
    }
}

// 门窗处理类
class DoorWindowProcessor {
    constructor(private scale: number) { }

    processWallWithDoors(
        startPoint: { x: number, y: number },
        endPoint: { x: number, y: number },
        thickness: number,
        doors: Door[]
    ): { wallSegments: WallSegment[], doorSegments: WallSegment[] } {
        const dirX = endPoint.x - startPoint.x;
        const dirZ = endPoint.y - startPoint.y;
        const wallLength = Math.sqrt(dirX * dirX + dirZ * dirZ);
        const dirNormalizedX = dirX / wallLength;
        const dirNormalizedZ = dirZ / wallLength;

        const sortedDoors = doors.slice().sort((a, b) => {
            const projA = DecoUtil.getProjectionDistance(a.pos.x, a.pos.y, startPoint, dirNormalizedX, dirNormalizedZ);
            const projB = DecoUtil.getProjectionDistance(b.pos.x, b.pos.y, startPoint, dirNormalizedX, dirNormalizedZ);
            return projA - projB;
        });

        const doorSegments: DoorSegment[] = sortedDoors.map(door => {
            const doorWidth = door.size.length * this.scale;
            const projDistance = DecoUtil.getProjectionDistance(door.pos.x, door.pos.y, startPoint, dirNormalizedX, dirNormalizedZ);
            return {
                start: projDistance - doorWidth / 2,
                end: projDistance + doorWidth / 2,
                door: door
            };
        });

        const wallSegments: WallSegment[] = [];
        const doorWallSegments: WallSegment[] = [];
        let currentPos = 0;

        for (const segment of doorSegments) {
            if (currentPos < segment.start) {
                const segmentStart = {
                    x: startPoint.x + dirNormalizedX * currentPos,
                    y: startPoint.y + dirNormalizedZ * currentPos
                };
                const segmentEnd = {
                    x: startPoint.x + dirNormalizedX * segment.start,
                    y: startPoint.y + dirNormalizedZ * segment.start
                };
                wallSegments.push({ start: segmentStart, end: segmentEnd, thick: thickness });
            }

            const doorStart = {
                x: startPoint.x + dirNormalizedX * segment.start,
                y: startPoint.y + dirNormalizedZ * segment.start
            };
            const doorEnd = {
                x: startPoint.x + dirNormalizedX * segment.end,
                y: startPoint.y + dirNormalizedZ * segment.end
            };
            const doorThickness = segment.door.size.thick * this.scale;
            doorWallSegments.push({ start: doorStart, end: doorEnd, thick: doorThickness });

            currentPos = segment.end;
        }

        if (currentPos < wallLength) {
            const segmentStart = {
                x: startPoint.x + dirNormalizedX * currentPos,
                y: startPoint.y + dirNormalizedZ * currentPos
            };
            wallSegments.push({ start: segmentStart, end: endPoint, thick: thickness });
        }

        return { wallSegments, doorSegments: doorWallSegments };
    }
}

// 网格合并类
class MeshCombiner {
    createCombinedMesh(geometryDataArray: WallGeometryData[], name: string, material: Material, collider: Boolean = false): Node {
        if (geometryDataArray.length === 0) return null;

        let totalVertices = 0;
        let totalIndices = 0;

        for (const data of geometryDataArray) {
            totalVertices += data.positions.length / 3;
            totalIndices += data.indices.length;
        }

        const mergedData = {
            positions: new Float32Array(totalVertices * 3),
            normals: new Float32Array(totalVertices * 3),
            uvs: new Float32Array(totalVertices * 2),
            indices: new Uint32Array(totalIndices),
            colors: new Float32Array(totalVertices * 4)
        };

        let vertexOffset = 0;
        let positionOffset = 0;
        let normalOffset = 0;
        let uvOffset = 0;
        let indexOffset = 0;
        let colorOffset = 0;

        for (const data of geometryDataArray) {
            const vertexCount = data.positions.length / 3;

            mergedData.positions.set(data.positions, positionOffset);
            mergedData.normals.set(data.normals, normalOffset);
            mergedData.uvs.set(data.uvs, uvOffset);

            if (data.colors) {
                mergedData.colors.set(data.colors, colorOffset);
            }

            for (let i = 0; i < data.indices.length; i++) {
                mergedData.indices[indexOffset + i] = data.indices[i] + vertexOffset;
            }

            vertexOffset += vertexCount;
            positionOffset += data.positions.length;
            normalOffset += data.normals.length;
            uvOffset += data.uvs.length;
            indexOffset += data.indices.length;
            colorOffset += data.colors ? data.colors.length : vertexCount * 4;
        }

        const boundingBox = DecoUtil.calculateBoundingBox(Array.from(mergedData.positions));
        const tangent = DecoUtil.calculateTangents(
            Array.from(mergedData.positions),
            Array.from(mergedData.normals),
            Array.from(mergedData.uvs),
            Array.from(mergedData.indices)
        );


        const meshOptions: any = {
            positions: Array.from(mergedData.positions),
            normals: Array.from(mergedData.normals),
            uvs: Array.from(mergedData.uvs),
            indices: Array.from(mergedData.indices),
            tangents: tangent,
            minPos: boundingBox.minPos,
            maxPos: boundingBox.maxPos
        };

        if (mergedData.colors.some(c => c !== 0)) {
            meshOptions.colors = Array.from(mergedData.colors);
        }

        const mesh = utils.MeshUtils.createMesh(meshOptions);
        mesh.name = name;

        const node = new Node(name);
        node.parent = BuildCtrl.ins.room;
        const meshRenderer = node.addComponent(MeshRenderer);
        if (collider && !EDITOR_NOT_IN_PREVIEW) {
            const obj = node.addComponent(Object3D);
            obj.useTriangle = true;
            obj.debug = true;
            obj.meshCollider = mesh;
            obj.manaulBuild(boundingBox.minPos, boundingBox.maxPos, mergedData.positions, mergedData.indices);

        }
        meshRenderer.mesh = mesh;
        meshRenderer.material = material;

        return node;
    }
}

// 墙体生成器主类
class WallGenerator {
    private extensionCalculator: WallExtensionCalculator;
    private geometryGenerator: WallGeometryGenerator;
    private doorWindowProcessor: DoorWindowProcessor;
    private meshCombiner: MeshCombiner;

    constructor(private dataManager: RoomDataManager, private scale: number, private wallHeight: number) {
        this.extensionCalculator = new WallExtensionCalculator(dataManager, scale);
        this.geometryGenerator = new WallGeometryGenerator(scale);
        this.doorWindowProcessor = new DoorWindowProcessor(scale);
        this.meshCombiner = new MeshCombiner();
    }

    createWalls(roomContent: RoomContent): Node {
        if (!roomContent.walls || !roomContent.wallpoints) return;

        const extendedGeometries = this.extensionCalculator.calculateWallExtensions();
        const wallDoors = this.groupDoorsByWall(roomContent.doors);

        const wallTopsData: WallGeometryData[] = [];
        const wallSidesData: WallGeometryData[] = [];
        const doorsData: WallGeometryData[] = [];


        const normalHeight = this.wallHeight * this.scale;
        const lowHeight = normalHeight * 0.75; // 减少40%，即保留60%

        // 处理每面墙
        for (const geometry of extendedGeometries) {
            const doors = wallDoors.get(geometry.wallId) || [];
            const startPoint = geometry.extendedStart || geometry.startPoint;
            const endPoint = geometry.extendedEnd || geometry.endPoint;

            // 判断是否为客厅和阳台独有的墙
            const isLowWall = this.isLivingRoomOrBalconyExclusiveWall(geometry.wallId);
            const wallHeight = isLowWall ? lowHeight : normalHeight;

            if (doors.length === 0) {
                // 没有门窗的墙体
                this.addWallTopGeometry(wallTopsData, startPoint, endPoint, geometry.thickness, wallHeight + 0.001);
                this.addWallSideGeometry(wallSidesData, startPoint, endPoint, geometry.thickness, wallHeight);
            } else {
                // 有门窗的墙体
                const { wallSegments, doorSegments } = this.doorWindowProcessor.processWallWithDoors(
                    startPoint, endPoint, geometry.thickness, doors
                );
                // 处理墙体段落
                for (const segment of wallSegments) {
                    this.addWallTopGeometry(wallTopsData, segment.start, segment.end, segment.thick, wallHeight + 0.001);
                    this.addWallSideGeometry(wallSidesData, segment.start, segment.end, segment.thick, wallHeight);
                }

                // 处理门窗段落
                for (const segment of doorSegments) {
                    this.addDoorGeometry(doorsData, segment.start, segment.end, segment.thick, wallHeight);
                }
            }
        }

        // 创建合并后的网格 - 普通高度墙体
        return this.createCombinedMeshes(wallTopsData, wallSidesData, doorsData, 'Normal');
    }

    // 判断墙是否为客厅和阳台独有
    private isLivingRoomOrBalconyExclusiveWall(wallId: string): boolean {
        return this.dataManager.isWallExclusiveToRooms(wallId, ['客厅', '厨房', '客餐厅', '阳台']);
    }

    private groupDoorsByWall(doors: Door[]): Map<string, Door[]> {
        const wallDoors = new Map<string, Door[]>();

        if (doors) {
            for (const door of doors) {
                if (!door.wallid) continue;
                if (!wallDoors.has(door.wallid)) {
                    wallDoors.set(door.wallid, []);
                }
                wallDoors.get(door.wallid).push(door);
            }
        }

        return wallDoors;
    }

    private addWallTopGeometry(
        geometryData: WallGeometryData[],
        startPoint: Point,
        endPoint: Point,
        thickness: number,
        height: number
    ): void {
        const { positions, normals, uvs } = this.geometryGenerator.generateWallGeometry(
            startPoint, endPoint, thickness, height, 'top'
        );
        geometryData.push({
            colors: COLORS.TOP.slice(0, 16),
            positions,
            indices: INDICES.TOP,
            normals,
            uvs
        });
    }

    private addWallSideGeometry(
        geometryData: WallGeometryData[],
        startPoint: Point,
        endPoint: Point,
        thickness: number,
        height: number
    ): void {
        const { positions, normals, uvs } = this.geometryGenerator.generateWallGeometry(
            startPoint, endPoint, thickness, height, 'side'
        );
        geometryData.push({
            colors: COLORS.SIDE,
            positions,
            indices: INDICES.SIDE,
            normals,
            uvs
        });
    }

    private addDoorGeometry(
        geometryData: WallGeometryData[],
        startPoint: Point,
        endPoint: Point,
        thickness: number,
        height: number
    ): void {
        const { positions, normals, uvs } = this.geometryGenerator.generateWallGeometry(
            startPoint, endPoint, thickness, height, 'full'
        );
        geometryData.push({
            colors: COLORS.DOOR,
            positions,
            indices: INDICES.DOOR,
            normals,
            uvs
        });
    }

    private createCombinedMeshes(
        wallTopsGeometryData: WallGeometryData[],
        wallSidesGeometryData: WallGeometryData[],
        doorsGeometryData: WallGeometryData[],
        suffix: string = ''
    ) {
        const meshSuffix = suffix ? `_${suffix}` : '';

        if (wallTopsGeometryData.length > 0) {
            const top = this.meshCombiner.createCombinedMesh(
                wallTopsGeometryData,
                `WallTopsMesh${meshSuffix}`,
                BuildCtrl.ins.wallTopMaterial || BuildCtrl.ins.wallMaterial
            );
            top.layer = 1 << 0;
        }
        let wall

        if (wallSidesGeometryData.length > 0) {
            wall = this.meshCombiner.createCombinedMesh(
                wallSidesGeometryData,
                `WallSidesMesh${meshSuffix}`,
                BuildCtrl.ins.wallMaterial, true
            );
            wall.layer = Layers.Enum.UI_3D;
        }
        if (doorsGeometryData.length > 0) {
            const door = this.meshCombiner.createCombinedMesh(
                doorsGeometryData,
                `DoorsMesh${meshSuffix}`,
                BuildCtrl.ins.doorMaterial
            );
            door.layer = 1 << 0;
        }
        return wall;
    }
}

// 主控制器类
class RoomBuilder extends Component {
    private wallHeight: number = CONSTANTS.WALL_HEIGHT;
    scale: number = CONSTANTS.SCALE;
    public bestPos: any = {};
    public type = ["sofa", 'bed', 'table', 'chair'];
    public scales = [0.9,1.1, 0.7, 0.35];
    public rotate = [-90, 90, 90, -90];
    public roomContent: RoomContent = null;

    // 各个功能模块 - dataManager 现在集成了所有数据管理功能
    public readonly dataManager = new RoomDataManager();
    private floorGenerator = new FloorGenerator(this.dataManager);
    private lightGenerator = new LightGenerator(this.dataManager, this.wallHeight, this.scale);
    private furniturePositioner = new FurniturePositioner(this.dataManager);
    private wallGenerator = new WallGenerator(this.dataManager, this.scale, this.wallHeight);

    private first = true;
    createRoom(roomContent: any): void {
        if(!this.first){
            // EventCtrl.instance.clearTest();
        }
        this.first = false;

        this.roomContent = roomContent;
        this.dataManager.init(roomContent);

        // 现在可以直接通过 dataManager 访问房间数据
        console.log("roominfo=", this.dataManager.getAllRoomData());

        this.cleanupResources();

        this.floorGenerator.createFloorsForRooms(roomContent);
        this.wallGenerator.createWalls(roomContent);
        this.lightGenerator.createRoomLights();
        if (!EDITOR_NOT_IN_PREVIEW) {
            DecoCtrl.ins.clear();

            this.scheduleOnce(() => {
                const roomWallPoints = this.furniturePositioner.getWallsForFurniturePosition(roomContent);

                this.bestPos = this.furniturePositioner.generateFurnitureBestPositions(roomWallPoints);

                const bestRadius = this.dataManager.houseInfo.width * 1.3;
                const room = DecoCtrl.ins.addRoom("全屋", bestRadius, { x: 0, y: 0 }, 0)
                room.onClick();
                DecoCtrl.ins.initRoomData(this.dataManager.getAllRoomData());

            })
        }




    }

    private cleanupResources(): void {
        const createdMeshes = BuildCtrl.ins.room.children;
        for (let i = createdMeshes.length - 1; i >= 0; i--) {
            const node = createdMeshes[i];
            if (node && node.isValid) {
                const meshRenderer = node.getComponent(MeshRenderer);
                if (meshRenderer) {
                    if (meshRenderer.mesh) {
                        meshRenderer.mesh.destroy();
                        meshRenderer.mesh = null;
                    }
                    meshRenderer.material = null;
                }
                node.destroy();
            }
        }
    }
}

const builder = new RoomBuilder();
export default builder;